#include <fhepython/PyCall.h>
#include <fhepython/PyEnv.h>

namespace fhe
{
  namespace python
  {
    PyCall::PyCall( const IFunc::Ptr& func )
      : func_( func )
    {
    }
    
    #define CALL_arg( z, n, unused ) args.push_back( PyEnv::instance().convertVal( BOOST_PP_CAT( a, n ) ) );
    
    #define CALL_iter( z, n, unused ) \
      boost::python::object PyCall::BOOST_PP_CAT( call, n )( BOOST_PP_ENUM_PARAMS( n, boost::python::object a ) ) \
      { \
        std::vector< Val > args; \
        BOOST_PP_REPEAT( n, CALL_arg, ~ ) \
        return PyEnv::instance().convertVal( func_->call( args ) ); \
      }
      
    BOOST_PP_REPEAT( FHE_ARGS, CALL_iter, ~ )
    
    #undef CALL_iter
    #undef CALL_arg
    
    boost::python::object PyCall::define()
    {
      return boost::python::class_<PyCall>( "Call", boost::python::no_init )
        #define CALL_iter( z, n, unused ) \
          .def( "__call__", &PyCall::BOOST_PP_CAT( call, n ) )
        BOOST_PP_REPEAT( FHE_ARGS, CALL_iter, ~ )
        #undef CALL_iter
      ;
    }
  }
}
